package org.loon.game.sample.llk;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import org.loon.framework.javase.game.action.sprite.WaitAnimation;
import org.loon.framework.javase.game.core.graphics.Screen;
import org.loon.framework.javase.game.core.graphics.component.LButton;
import org.loon.framework.javase.game.core.graphics.component.LMessage;
import org.loon.framework.javase.game.core.graphics.opengl.GLColor;
import org.loon.framework.javase.game.core.graphics.opengl.GLEx;
import org.loon.framework.javase.game.core.graphics.opengl.GLEx.Direction;
import org.loon.framework.javase.game.core.graphics.opengl.LTexture;
import org.loon.framework.javase.game.core.graphics.opengl.LTextureList;
import org.loon.framework.javase.game.core.input.LInputFactory.Touch;
import org.loon.framework.javase.game.core.input.LTouch;
import org.loon.framework.javase.game.core.timer.LTimerContext;
import org.loon.framework.javase.game.utils.GraphicsUtils;
import org.loon.framework.javase.game.utils.MathUtils;
import org.loon.framework.javase.game.utils.xml.XMLElement;
import org.loon.game.sample.llk.Map.xml.KXmlSerializer;
import org.loon.game.sample.llk.Map.xml.LXmlWriter;
import org.loon.game.sample.llk.Map.xml.MapTools;
import org.loon.game.sample.llk.Map.xml.PopMenu;
import org.loon.game.sample.llk.Map.xml.XmlSerializer;

public class LLKScreenx extends Screen {

	LTextureList list; 
	pGrid[][] lb; 
	int row = 2;
	int colm = 2;
	LvInfo lv = new LvInfo();
	
	boolean EditorMode = false;
	
	int mouseButton = -1;
	
	PopMenu pMenu= null;
	int allVisGrid;
	LMessage msg = null;
	
	public void onLoad() {
		list = new LTextureList("assets/images.xml");
		//row = lv.row;
		//colm = lv.colm;
		 initMenuUI();
		/*if (EditorMode) {
			initEditorUI();
		} else {
			initGameUIXml();
		}*/
	}
	
	private void showMsg(){
		if(msg == null){
			msg = new LMessage(0,0,getWidth(),getHeight()){
				public void doClick(){
					setVisible(false);
				}
			};
		}else{
			msg.setVisible(true);
		}
		msg.setLayer(102);
		msg.setMessage("可见的格子不是成对的");
		add(msg);
	}
	
	public void initLevelMeun(String filePath){
		//TODO
	}
	
	public void initPopMenu(){
		System.out.println("init Menu");
		pMenu = new PopMenu(150,250);
		LButton reSet = new LButton("重置",40,160,40,30){
			public void doClick(){
				//row++;
				row = pMenu.getRow();
				colm = pMenu.getClom();
				removeAll();
				initEditorUI();
			}
		};
		LButton save = new LButton("保存",40,200,40,30){
			public void doClick(){
				
				if(allVisGrid%2 != 0){
					showMsg();
					return ;
				}
				System.out.println("save");
				try {
					saveLvInfo();
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalStateException e) {
					e.printStackTrace();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		};
		LButton lbT = new LButton("开始",100,160,40,30){
	    	public void doClick(){
	    		removeAll();
	    		initGameUIXml();
	    	}
	    };
		pMenu.add(reSet);
		pMenu.add(save);
		pMenu.add(lbT);
	}
	
	public void saveLvInfo() throws IllegalArgumentException, IllegalStateException, IOException{	
		int tRow = row + 2;
		int tColm = colm + 2;
		LXmlWriter lxw = new LXmlWriter("output.xml");
		
		lxw.getXMLWriter().startTag("", "gameData");
		lxw.getXMLWriter().startTag("", "head");
		lxw.writeSingleTag("row", ""+row);
		lxw.writeSingleTag("colm", ""+colm);
		lxw.writeSingleTag("allVisGrid", ""+allVisGrid);
		lxw.getXMLWriter().endTag("", "head");
		lxw.getXMLWriter().startTag("", "body");
		for (int i = 0; i < tRow; i++) {
			for (int j = 0; j < tColm; j++) {
				if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
					lxw.getXMLWriter().startTag("","tile");
					lxw.getXMLWriter().attribute("", "x",""+i);
					lxw.getXMLWriter().attribute("", "y",""+j);
					lxw.getXMLWriter().text(lb[i][j].type);
					lxw.getXMLWriter().endTag("", "tile");
				} else {
					lxw.getXMLWriter().startTag("","tile");
					lxw.getXMLWriter().attribute("", "x",""+i);
					lxw.getXMLWriter().attribute("", "y",""+j);
					lxw.getXMLWriter().text(lb[i][j].type);
					lxw.getXMLWriter().endTag("", "tile");
				}
			}
		}
		lxw.getXMLWriter().endTag("", "body");
		lxw.getXMLWriter().endTag("", "gameData");
		lxw.end();
	}
	
	
	public void initMenuUI(){
	    this.setBackground(GLColor.red);
	    LButton lbT = new LButton("开始游戏",100,100,50,30){
	    	public void doClick(){
	    		removeAll();
	    		initGameUIXml();
	    	}
	    };
	    LButton lbE = new LButton("编辑游戏",100,140,50,30){
	    	public void doClick(){
	    		removeAll();
	    		initEditorUI();
	    	}
	    };
	    this.add(lbT);
	    this.add(lbE);
	}
	
	public void initWinUI(){
	    this.setBackground(GLColor.red);
	    removeAll();
	    LButton lbT = new LButton("WIN",100,100,100,100){
	    	public void doClick(){
	    		removeAll();
	    		initGameUIXml();
	    	}
	    };
	    this.add(lbT);
	}
	
	public void initEditorUI(){
		setBackground(GLColor.black);
		
		int tRow = row + 2;
		int tColm = colm + 2;
		int width = getWidth() / tRow;
		int height = getHeight() / tColm;
		int temp = width >= height ? height : width;
		
		allVisGrid = row*colm;
		
		lb = new pGrid[tRow][tColm];
		
		System.out.println("temp=" + temp );
		
		for (int i = 0; i < tRow; i++) {
			for (int j = 0; j < tColm; j++) {
				if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
					lb[i][j] = new pGrid( 0 + i * temp, 0 + j * temp,temp,temp,j,i,"N");  //注释要要颠倒xy
					lb[i][j].setVisible(false);
				} else {
					lb[i][j] = new pGrid( 0 + i * temp, 0 + j * temp,temp,temp,j,i,"R") {
						public void doClick() {
							clicked = !clicked;
							clickE();
							clicked = !clicked;
						}
					};
				}
				
				this.add(lb[i][j]);
			}
		}
		
		if(pMenu == null){
			initPopMenu();
		}
		
		add(pMenu);
	}
	
	public void initGameUIXml(){
		MapTools map = new MapTools();
		int NamesCount = map.getGradNum();
		
		row = map.getRow();
		colm = map.getColm();
		int tRow =row  + 2;
		int tColm =colm  + 2;
		int width = getWidth() / tRow;
		int height = getHeight() / tColm;
		
		int temp = width >= height ? height : width;
		int srcWidth = list.loadTexture("dota1").getWidth();
		float scaleRate = (float) (temp / (srcWidth + 0.0));
		//统一计算模式效率高，可以改为每张计算的模式
		
		lb = new pGrid[tRow][tColm];
		
		String[] images = initImage(8, NamesCount);
		ArrayList tiles = map.getLevelInfo();
		
		int count = 0;
		for (int i = 0; i < tiles.size(); i++) {
			XMLElement tile = (XMLElement) tiles.get(i);
			if (tile != null) {
				int x = Integer.valueOf(tile.getAttribute("x").getIntValue());
				int y = Integer.valueOf(tile.getAttribute("y").getIntValue());
				String key = tile.getContents();
				if (x == 0 || y == 0 || x == tRow - 1 || y == tColm - 1 || key.equals("N")) {
					lb[x][y] = new pGrid(list.loadTexture("dota1").scale(
							scaleRate), 0 + x * temp, 0 + y * temp,y,x,"dota1");  //注释要要颠倒xy
					lb[x][y].setVisible(false);
				} else {
					String name = (String)images[count];
					lb[x][y] = new pGrid(list.loadTexture(name).scale(
							scaleRate), 0 + x * temp, 0 + y * temp,y,x,name) {
						public void doClick() {
							clicked = !clicked;
							clickz();
						}
					};
					count++;
				}
				this.add(lb[x][y]);
			}
		}
		
	}
	
	
	public void initGameUI(){
		
		int tRow = row + 2;
		int tColm = colm + 2;
		int width = getWidth() / tRow;
		int height = getHeight() / tColm;

		int temp = width >= height ? height : width;
		int srcWidth = list.loadTexture("dota1").getWidth();
		float scaleRate = (float) (temp / (srcWidth + 0.0));
		//统一计算模式效率高，可以改为每张计算的模式
		System.out.println("temp=" + temp + " scaleRate=" + scaleRate
				+ " srcWidth" + srcWidth);

		lb = new pGrid[tRow][tColm];
		
		//String key = "";
		
		String[][] key = initImage(8);

		for (int i = 0; i < tRow; i++) {
			for (int j = 0; j < tColm; j++) {
				if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
					lb[i][j] = new pGrid(list.loadTexture("dota1").scale(
							scaleRate), 0 + i * temp, 0 + j * temp,j,i,"dota1");  //注释要要颠倒xy
					lb[i][j].setVisible(false);
				} else {
					//key = getImageName(8);
					//System.out.println("i="+i+"j"+j+key[i][j]);
					lb[i][j] = new pGrid(list.loadTexture(key[i][j]).scale(
							scaleRate), 0 + i * temp, 0 + j * temp,j,i,key[i][j]) {
						public void doClick() {
							clicked = !clicked;
							clickz();
						}
					};
				}
				
				this.add(lb[i][j]);
				if(lv.type == LvInfo.TYPE_GRID && (i+j)%2==1){
					lb[i][j].setVisible(false);
				}
				if(lv.noUseRow != null && lv.noUseRow[0]==j){
					lb[i][j].setVisible(false);
				}
			}
		}
	}
	
	
	public int getRndInt(int n){
		if(n==0)
			n=1;
		return new Random().nextInt(n)+1;
	}
	
	public String getImageName(int n){
		return "dota"+getRndInt(n);
	}
	
	public String[] initImage(int n, int allCount) {
		String[] images = new String[allCount];
		for (int i = 0; i < allCount/2; i++) {
			String key = getImageName(n);
			for (int j = 0; j < 2; j++) {
				int index = new Random().nextInt(allCount);
				//System.out.println("allCount=" + allCount + "index=" + index);
				if (images[index] == null || images[index].length() == 0) {
					images[index] = key;
				} else {
					j--;
				}
			}
		}
		return images;
	}
	
	public String[][] initImage(int n) { // 控制生成的图片种类
		int allNameCount = row * colm / 2;

		String[][] names = new String[row + 1][colm + 1];

		int count = 0;

		for (int i = 0; i < allNameCount; i++) {
			String key = getImageName(n);
			for (int j = 0; j < 2; j++) {
				int x = getRndInt(row);
				int y = getRndInt(colm);
				if (names[x][y] == null || names[x][y].length() <= 0) {
					names[x][y] = key;
				} else {
					j--;
				}
				count++;
			}
		}

		return names;
	}
	
	
	public void clickE() {
		System.out.println("edit clicked!");
		System.out.println("mouseButton=" + mouseButton);
		ArrayList<pGrid> cps = (ArrayList) this.getComponents(pGrid.class);
		for (int i = 0; i < cps.size(); i++) {
			pGrid b = cps.get(i);
			if (b.clicked && b.isVisible() && !b.type.equals("N")) {
				if (mouseButton == Touch.RIGHT) {
					b.type = "N";
					allVisGrid--;
					break;
				}
			}else if (b.clicked && b.isVisible() && b.type.equals("N")){
				if(mouseButton == Touch.RIGHT){
					b.type = "R";
					allVisGrid++;
					break;
				}
			}
		}
		mouseButton = -1;
	}
	
	public void clickz(){
		
		System.out.println("clicked");
		
		int count = 0;
		
		pGrid frist = null,next = null;
		ArrayList<pGrid>cps = (ArrayList)this.getComponents(pGrid.class);
		for(int i=0;i<cps.size();i++){
			pGrid b = cps.get(i);
			if(b.clicked && b.isVisible()){
				count ++;
				if(frist == null ){
					frist = b;
				}else if(next == null ){
					next = b;
				}
				
			}
		}
		
		System.out.println(count);
		
		if(count ==2 && frist.type.equals(next.type) &&findPath(frist,next)){		
			frist.setVisible(false);
			next.setVisible(false);
			frist.clicked = false;
			next.clicked = false;
			if(lv.inType > 0){
				reSetMap();
			}
		}else if(count ==2){
			frist.clicked = false;
			next.clicked = false;
		}
		if(needrefresh()){
			System.out.println("need refresh");
			refreshx();
		}
	}
	
	
	private void reSetMap() {
		int tRow = row + 2;
		int tColm = colm + 2;
		
		if (lv.inType == LvInfo.INTYPE_ROW_LEFT) {
			for (int j = 0; j < tColm; j++) {

				List<pGrid> listv = new LinkedList<pGrid>();
				List<pGrid> listNov = new LinkedList<pGrid>();
				for (int i = 0; i < tRow; i++) {

					if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
					} else {
						if (lb[i][j].isVisible()) {
							listv.add(lb[i][j]);
						} else {
							listNov.add(lb[i][j]);
						}
					}
				}
				int count = 0;
				for (int i = 0; i < tRow; i++) {
					if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
					} else {
						// lb[i][j] = listv.get(count);
						// System.out.println("count="+count);
						if (count < listv.size()) {
							exChgGrid(lb[i][j], listv.get(count));
							// lb[i][j] = new pGrid(listv.get(count));
						}
						count++;
					}
				}
			}
		} else if (lv.inType == LvInfo.INTYPE_ROW_RIGHT) {
			System.out.println("start reSet Right");
			for (int j = 0; j < tColm; j++) {

				List<pGrid> listv = new LinkedList<pGrid>();
				List<pGrid> listNov = new LinkedList<pGrid>();
				for (int i = tRow-1; i >0 ; i--) {

					if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
					} else {
						if (lb[i][j].isVisible()) {
							listv.add(lb[i][j]);
						} else {
							listNov.add(lb[i][j]);
						}
					}
				}
				int count = 0;
				for (int i = tRow-1; i >0; i--) {
					if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
					} else {
						// lb[i][j] = listv.get(count);
						//System.out.println("count="+count+"size()="+listv.size());
						if (count < listv.size()) {
							exChgGrid(lb[i][j], listv.get(count));
							 //lb[i][j] = new pGrid(listv.get(count));
							//lb[i][j];
							//listv.get(count);
						}
						count++;
					}
				}
			}
		}
	}
	
	public void exChgGrid(pGrid src,pGrid dst){
		pGrid tmp = new pGrid(src);
		
		src.setShow(dst.getShow());
		src.type = dst.type;
		src.setVisible(dst.isVisible());

		dst.setShow(tmp.getShow());
		dst.type = tmp.type;
		dst.setVisible(tmp.isVisible());
		
	}
	
	public void refreshx(){
		
		int tRow = row + 2;
		int tColm = colm + 2;
		
		int vCount = 0;
		
		for (int i = 0; i < tRow; i++) {
			for (int j = 0; j < tColm; j++) {
				if (i == 0 || j == 0 || i == tRow - 1 || j == tColm - 1) {
				} else {
					if(lb[i][j].isVisible()){
						pGrid tmp = new pGrid(lb[i][j]);
						int x = getRndInt(row);
						int y = getRndInt(colm);
						
						if(lb[x][y].isVisible()){
							lb[i][j].setShow(lb[x][y].getShow());
							lb[i][j].type = lb[x][y].type;
							
							lb[x][y].setShow(tmp.getShow());
							lb[x][y].type = tmp.type;
							
							vCount++;
						}else{
							j--;
						}
					}
				}
				//this.add(lb[i][j]);
			}
		}
		
		if(vCount == 0){
			initWinUI();//此处初始化游戏胜利
		}
	}
	
	public boolean needrefresh(){
		return new PathFinder(lb,row+2,colm+2).needResh();
	}
	
	public boolean findPath(pGrid frist,pGrid next){
		
		PathFinder pf = new PathFinder(lb,row+2,colm+2);
//		System.out.println("path num="+pf.findPath(frist, next));
		int pNum = pf.findPath(frist, next);
		System.out.println("path num="+pNum);
		return pNum > 0? true: false;
	}
	
	@Override
	public void alter(LTimerContext arg0) {
		
	}

	private WaitAnimation wait = new WaitAnimation(0, 320, 240);
	@Override
	public void draw(GLEx g) {
		// TODO Auto-generated method stub
		if (!isOnLoadComplete()) {
			wait.draw(g, 0, 0, getWidth(), getHeight());
		}
		//g.setColor(GLColor.blue);
		//g.drawString("xxxxxxxxxxxxxxxxx", 100, 100);
		//g.resetColor();
	}

	@Override
	public void touchDown(LTouch e) {
		mouseButton = e.getButton();
	}

	@Override
	public void touchDrag(LTouch arg0) {

	}

	@Override
	public void touchMove(LTouch arg0) {
		
	}

	@Override
	public void touchUp(LTouch arg0) {
		//mouseButton = -1;
	}

}
